Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag. 是什么原因?

————————

这个报错的根本原因是:Java 编译器在默认情况下,不会将方法的参数名(例如 iduserId)保留在编译后的 .class 字节码文件中。

当你使用 Spring Boot(尤其是 Spring Boot 3.x)或其他依赖反射获取参数名的框架时,如果代码中没有显式指定参数名,框架在运行时会尝试通过反射去读取真实的参数名。由于编译时参数名被丢弃了,框架读不到名字,就会抛出这个异常。

这个问题通常出现在使用 @PathVariable@RequestParam@RequestHeader@Cacheable 等注解,且没有给注解指定具体名称的时候。

你可以通过以下两种方案来解决这个问题:

方案一:全局配置开启 -parameters 编译选项(强烈推荐)

这是最彻底的解决方式,能让框架在运行时通过反射正常获取到参数名,无需修改业务代码。根据你使用的构建工具,进行如下配置:

  • 如果你使用的是 Maven: 在项目的 pom.xml 文件中,为 maven-compiler-plugin 插件添加 -parameters 参数:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version> <!-- 建议使用较新版本 -->
                <configuration>
                    <!-- 直接开启 parameters 选项 -->
                    <parameters>true</parameters>
                    <!-- 或者使用 compilerArgs 方式 -->
                    <!--
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                    -->
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 如果你使用的是 Gradle: 在 build.gradle 文件中添加以下配置:

    tasks.withType(JavaCompile) {
        options.compilerArgs << '-parameters'
    }
  • 如果你使用的是 IntelliJ IDEA(仅本地开发): 可以通过 IDE 设置开启:进入 Settings/Preferences -> Build, Execution, Deployment -> Compiler -> Java Compiler,在 Additional command line parameters 中添加 -parameters

方案二:在注解中显式指定参数名(快速修复)

如果你不想改动构建配置,或者只需要快速修复某一个接口的报错,可以在注解中手动写上参数的名字。

例如,将报错的代码:

@GetMapping("/{id}")
public Result<User> getById(@PathVariable Long id) { ... }

修改为显式指定名称:

@GetMapping("/{id}")
public Result<User> getById(@PathVariable("id") Long id) { ... }

建议优先采用方案一,配置好构建工具后,重新执行一次 clean 和 compile(或重启项目),这个问题就会彻底解决。